package com.sfjswl.fp.core.utils;

import com.sfjswl.fp.common.enums.NodeRunStateEnum;
import com.sfjswl.fp.core.base.BaseNode;
import com.sfjswl.fp.core.context.RuleContext;
import com.sfjswl.fp.core.context.RuleParallelContext;
import com.sfjswl.fp.core.handler.RuleHandler;
import lombok.AllArgsConstructor;
import lombok.Data;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;

@Data
@AllArgsConstructor
public final class RuleExecutor {

    private static ThreadPoolExecutor executor;

    public static void setExecutor(ThreadPoolExecutor executor) {
        if (executor == null) {
            throw new NullPointerException("rule executor can not null");
        }
        RuleExecutor.executor = executor;
    }

    public static Future<NodeRunStateEnum> submitNodeCallable(BaseNode node, RuleParallelContext ctx) {
        return executor.submit(() -> {
            if (!ctx.isDone()) {
                return node.process(ctx.getCtx());
            }
            return NodeRunStateEnum.NONE;
        });
    }

    public static Future<NodeRunStateEnum> submitNodeCallable(BaseNode node, RuleContext ctx) {
        return executor.submit(() -> node.process(ctx));
    }

    public static Future<?> submitNodeRunnable(BaseNode node, RuleContext ctx) {
        return executor.submit(() -> {
            node.process(ctx);
        });
    }

    public static Future<RuleContext> submitHandler(RuleHandler handler, RuleContext ctx) {
        return executor.submit(() -> {
            handler.handle(ctx);
            return ctx;
        });
    }
}
